﻿using System;
using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Application.Interface;
using Domain;
using Domain.Dto;
using Domain.Dto.SampleModel.Event;
using Domain.Dto.User;
using Domain.Interface;
using Domain.Model;
using Domain.Services;
using Domain.Specification;
using DotNetCore.CAP;
using Gmmy.ApplicationExtension;
using Gmmy.DomainExtension;
using Gmmy.RepositoryExtension;
using Gmmy.Utility;
using Gmmy.Utility.Enums;
using Infrastructure.Common.Enums;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Surging.Core.Caching;
using Surging.Core.CPlatform.Cache;
using Surging.Core.ProxyGenerator;
using Surging.Core.CPlatform.Ioc;
using Surging.Core.CPlatform.Utilities;

namespace Application.Services
{
    [ModuleName("User")]
    public class UserService :
        BaseServices<User>,
        IUserService
    {
        private readonly IUserDomainService _domainService;
        private readonly IUserRepoistory _repository;
        private readonly ILogger<UserService> _logger;
        private readonly IServiceProxyProvider _serviceProxyProvider;
        private readonly IUserRoleRepository _userRoleRepository;

        private readonly ICapPublisher _publisher;
        public UserService(
            IUserDomainService domainService,
            IUserRepoistory repository,
            ILogger<UserService> logger,
            IServiceProxyProvider serviceProxyProvider,
            IUserRoleRepository userRoleRepository, ICapPublisher publisher
        ) : base(repository, logger)
        {
            _domainService = domainService;
            _repository = repository;
            _serviceProxyProvider = serviceProxyProvider;
            _userRoleRepository = userRoleRepository;
            _publisher = publisher;
        }

        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<CustomApiResult> Login(LoginInput input)
        {
            return await Do(input, async result =>
            {
                result.data =
                    await _domainService.LoginAccount(input.LoginName, input.Password, input.RandomKey, input.GetRequestInfo());
                await base.CommitAsync();
            });

        }

        /// <summary>
        /// 获取用户基本信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<CustomApiResult> Info(EmptyRequest input)
        {
            return await Do(async result =>
            {
                var userInfo = input.GetAuthInfo();
                var (actions, roleName) = await _userRoleRepository.GetAllUserRoles(userInfo.ID);
                result.data = new FullLoginInfoDto
                {
                    UserInfo = userInfo,
                    Actions = actions,
                    Roles = roleName
                };
            });
        }

        /// <summary>
        /// 修改用户基本信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<CustomApiResult> ChangeUserInfo(UpdateUserInput input)
        {
            return await Do(async result =>
            {
                var userDto = await _domainService.ChangeUserInfo(input);
                await base.CommitAsync();
                //发布用户信息修改成功的事件
                if (input.ID == null || input.ID == input.GetAuthInfo().ID)
                {
                    await _publisher.PublishAsync("Gmmy.Microservices.UserServices.ChangeUserInfo", new
                    {
                        UserInfo = userDto,
                        Token = input.Token
                    });
                }
            });
        }

        /// <summary>
        /// 获取用户列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<CustomApiResult> GetList(UserListInput input)
        {
            return await Do(input, async result =>
            {
                result.data = await _repository.GetList(input, new UserListSpecification(input));
            });
        }

        /// <summary>
        /// 获取用户详情
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<CustomApiResult> Get(GetInput input)
        {
            return await Do(input, async result =>
            {
                result.data = new
                {
                    UserInfo = await _repository.GetByConditionAsync(
                        new DirectSpecification<User>(x => !x.IsDeleted && x.ID == input.ID)),
                    Roles = (await _userRoleRepository.GetManyAsync(
                        new DirectSpecification<UserRole>(x => !x.IsDeleted && x.UserId == input.ID)))
                    .Select(x => x.RoleId)
                };
            });
        }

        public async Task<CustomApiResult> CreateUserInfo(UpdateUserInput input)
        {
            return await Do(input, async result =>
            {
                await _domainService.CreateUserInfo(input);
                await base.CommitAsync();
            });
        }

        public async Task<CustomApiResult> ChangeUserState(GetInput input)
        {
            return await Do(input, async result =>
            {
                var newState= await _domainService.ChangeUserState(input);
                result.message = $"用户状态已变更为{newState.GetLocalizedDescription()}!";
                await base.CommitAsync();
            });
        }
    }
}
